package com.jy.api.controller.admin;

import com.jy.api.dao.*;
import com.jy.api.domain.*;
import com.jy.api.enums.DistributeType;
import com.jy.api.enums.StoreLevel;
import com.jy.api.exception.MyException;
import com.jy.api.payRes.CouponInstanceDto;
import com.jy.api.service.CouponService;
import com.jy.api.signUpReq.admin.CouponSignUpReq;
import com.jy.api.signUpReq.admin.DistributeCouponSignUpReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import javax.validation.Valid;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lihu on 2017/11/17.
 */
@Slf4j
@RestController
@RequestMapping(value = "v1/admin/", produces = "application/json;charset=utf-8")
public class CouponController {

    @Autowired
    CouponService couponService;

    @Autowired
    EmployeeDao employeeDao;

    @Autowired
    StoreDao storeDao;
    @Autowired
    StoreConfigDao storeConfigDao;
    @Autowired
    private CouponDao couponDao;
    @Autowired
    private CouponInstanceDao couponInstanceDao;
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private ProductDao productDao;


    /**
     * 优惠卷派发
     *
     * @param signUpReq
     * @return
     */
    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(method = RequestMethod.POST, value = "/distribute-coupon")
    public ResponseEntity distributeCoupon(@Valid @RequestBody DistributeCouponSignUpReq signUpReq,
                                           BindingResult bindingResult, Principal principal) {
        try {
            if (bindingResult.hasErrors()) {
                return new ResponseEntity(bindingResult.getFieldError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
            }
            Store store = storeDao.findOne(signUpReq.getStoreId());
            if (store == null) {
                return new ResponseEntity("派发失败！店铺信息有误！！", HttpStatus.BAD_REQUEST);
            }

            if (store.getLevel() != StoreLevel.THREE) {
                return new ResponseEntity("当前店铺版本过低！请升级！", HttpStatus.BAD_REQUEST);
            }

            Employee employee = employeeDao.findByStoreIdAndUsernameAndEnabled(signUpReq.getStoreId(),
                    principal.getName(), true);
            if (employee == null) {
                return new ResponseEntity("派发失败！账号信息有误！", HttpStatus.BAD_REQUEST);
            }
            Coupon coupon = couponService.getFondId(signUpReq.getCouponId());
            if (coupon == null || !coupon.isEnabled()) {
                return new ResponseEntity("派发失败！优惠卷信息不存在！", HttpStatus.BAD_REQUEST);
            }

            if (signUpReq.getDistributeType() == DistributeType.SINGLE && signUpReq.getMemeberIds().size() == 0) {
                return new ResponseEntity("派发失败！未选择派发会员信息！", HttpStatus.BAD_REQUEST);
            }
            log.info("门店{}, 派发人{}, 派发优惠券{}, 派发数量{}, 收券人{}", signUpReq.getStoreId(), employee.getName(), coupon, signUpReq.getQty(), signUpReq.getMemeberIds());
            couponService.distributeCoupon(signUpReq, coupon, employee.getUsername(), employee.getName());
            return new ResponseEntity(HttpStatus.OK);
        } catch (Exception ex) {
            log.error("getCouponInstance  is error==> signUpReq{}", signUpReq, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

    /**
     * 删除优惠卷
     *
     * @param id
     * @return
     */
    @RequestMapping(method = RequestMethod.DELETE, value = "coupon")
    public ResponseEntity deleteCoupon(@RequestParam(value = "id") String id) {
        couponService.deleteCoupon(id);
        return new ResponseEntity(HttpStatus.OK);
    }


    /**
     * 获取优惠卷信息
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/coupon")
    public ResponseEntity coupon(@RequestParam(value = "storeId") String storeId, @RequestParam("status") CouponStatus couponStatus,
                                 @PageableDefault(value = 10, sort = {"addTime"},
                                         direction = Sort.Direction.DESC) Pageable pageable) {
        return new ResponseEntity(couponService.getCouponAll(storeId, couponStatus, pageable), HttpStatus.OK);
    }

    /**
     * 获取优惠卷信息
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/coupon/list")
    public ResponseEntity couponList(@RequestParam(value = "storeId") String storeId, @PageableDefault(value = 10, sort = {"addTime"},
            direction = Sort.Direction.DESC) Pageable pageable) {
        return new ResponseEntity(couponService.getCouponAll(storeId, pageable), HttpStatus.OK);
    }

    /**
     * 暂停优惠券
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/stop/coupon")
    public ResponseEntity stopCoupon(@RequestParam(value = "id") String id) {
        Coupon coupon = couponDao.findOne(id);
        if (coupon == null) {
            return new ResponseEntity("优惠券不存在，请刷新后重试", HttpStatus.BAD_REQUEST);
        }
        StoreConfig storeConfig = storeConfigDao.findByStoreId(coupon.getStoreId());
        if (storeConfig != null) {
            if (coupon.getId().equals(storeConfig.getGiveCouponId())) {
                return new ResponseEntity("该优惠券在（新增会员自动派券）活动中使用，请先取消该活动后再试", HttpStatus.BAD_REQUEST);
            }
        }
        if (coupon.getStatus().equals(CouponStatus.NO) || coupon.getStatus().equals(CouponStatus.ING)) {
            coupon.setStatus(CouponStatus.STOP);
            couponDao.save(coupon);
            return new ResponseEntity(HttpStatus.OK);
        } else {
            return new ResponseEntity("优惠券状态仅未开始/进行中才能暂停", HttpStatus.BAD_REQUEST);
        }

    }

    /**
     * 暂停会员优惠券
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/stop/member/coupon")
    public ResponseEntity stopMemberCoupon(@RequestParam(value = "id") String id) {
        CouponInstance coupon = couponInstanceDao.findOne(id);
        if (coupon == null) {
            return new ResponseEntity("优惠券不存在，请刷新后重试", HttpStatus.BAD_REQUEST);
        }
        if (!coupon.getStauts().equals(CouponInstanceStatus.NORMAL)) {
            return new ResponseEntity("优惠券不是正常状态，请刷新后重试", HttpStatus.BAD_REQUEST);
        }
        coupon.setStauts(CouponInstanceStatus.STOP);
        couponInstanceDao.save(coupon);
        return new ResponseEntity(HttpStatus.OK);
    }


    /**
     * 新增或者修改优惠卷
     *
     * @param couponSignUpReq
     * @param bindingResult
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "coupon")
    public ResponseEntity saveCoupon(@Valid @RequestBody CouponSignUpReq couponSignUpReq,
                                     BindingResult bindingResult) {
        try {
            if (StringUtils.isBlank(couponSignUpReq.getProductId())) {
                return new ResponseEntity("未指定优惠券使用商品", HttpStatus.BAD_REQUEST);
            }
            Store store = storeDao.findOne(couponSignUpReq.getStoreId());
            if (store.getLevel() != StoreLevel.THREE) {
                return new ResponseEntity("店铺等级不足！请升级店铺等级", HttpStatus.BAD_REQUEST);
            }
           /* if (couponSignUpReq.getType().equals(CouponType.REDUCE)){
               List<String> productIds = Lists.newArrayList(couponSignUpReq.getProductId().split(","));
               List<Product> products = productDao.findAllByIdInOrderBySalesPriceAsc(productIds);
               if (products.size()>0&&couponSignUpReq.getCouponAmount()>){

               }
            }*/


            couponService.saveOrUpdate(couponSignUpReq);
            return new ResponseEntity(HttpStatus.OK);
        } catch (MyException ex) {
            log.error("saveCoupon is error=>couponSignUpReq:{}", couponSignUpReq, ex);
            return new ResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
        } catch (Exception ex) {
            log.error("saveCoupon is error=>couponSignUpReq:{}", couponSignUpReq, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }


    /**
     * 优惠卷详情
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/coupon/detail")
    public ResponseEntity couponDetail(@RequestParam("memberId") String memberId, @RequestParam("status") CouponInstanceStatus status,
                                       @RequestParam("couponId") String couponId, @PageableDefault(value = 10) Pageable pageable) {
        Coupon coupon = couponDao.findOne(couponId);
        if (coupon == null) {
            return new ResponseEntity("优惠券不存在，请刷新后重试", HttpStatus.BAD_REQUEST);
        }
        Specification<CouponInstance> spec = (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(memberId)) {
                predicates.add(criteriaBuilder.equal(root.get("ownerId"), memberId));
            }
            if (!status.equals(CouponInstanceStatus.STOP)) {
                predicates.add(criteriaBuilder.notEqual(root.get("stauts"), CouponInstanceStatus.STOP));
            } else {
                predicates.add(criteriaBuilder.equal(root.get("stauts"), status));
            }
            predicates.add(criteriaBuilder.equal(root.get("couponId"), couponId));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<CouponInstance> couponInstances = couponInstanceDao.findAll(spec, new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(Sort.Direction.DESC, "addTime", "ownerId")));
        List<CouponInstanceDto> couponInstanceDtos = new ArrayList<>();
        for (CouponInstance couponInstance : couponInstances) {
            if (!StringUtils.isBlank(couponInstance.getOwnerId())) {
                Member member = memberDao.findOne(couponInstance.getOwnerId());
                CouponInstanceDto dto = new CouponInstanceDto();
                BeanUtils.copyProperties(couponInstance, dto);
                dto.setMemberName(member.getName());
                dto.setMobile(null == member.getMobile() ? "" : member.getMobile());
                couponInstanceDtos.add(dto);
            }
        }
        Map map = new HashMap();
        map.put("data", couponInstanceDtos);
        map.put("totalElements", couponInstances.getTotalElements());
        map.put("totalPages", couponInstances.getTotalPages());
        return new ResponseEntity(map, HttpStatus.OK);
    }
}
